package edu.rpi.tw.impav;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.store.LockObtainFailedException;

import twitter4j.Status;
import twitter4j.StatusDeletionNotice;
import twitter4j.StatusListener;
import twitter4j.TwitterException;
import twitter4j.TwitterStream;
import twitter4j.TwitterStreamFactory;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;

import com.hp.hpl.jena.ontology.Individual;

public class TweetQueue implements StatusListener {

    private ConceptMap concepts = null;
    private TwitterStream twitter;
    private TwitterStreamFactory factory = new TwitterStreamFactory();
    
    private String consumerKey = "HXHN6Lq2juGo1MXCJizOcw";
    private String consumerSecret = "4SIuARqzp5AAPkoGZoAVTm2XBsW0XtWiPYNnk0pD8RI";
    
    private BlockingQueue<Tweet> tweets = new LinkedBlockingQueue<Tweet>();
    
    public TweetQueue(String fileOrURI) throws CorruptIndexException, LockObtainFailedException, IOException, TwitterException, BackingStoreException {
        twitter = factory.getOAuthAuthorizedInstance(consumerKey, consumerSecret);
        twitter.setOAuthAccessToken(getAccessToken());
        twitter.setStatusListener(this);
        System.out.println("Loading Concepts...");
        concepts = new ConceptMap(fileOrURI);
        System.out.println("Done.");
    }

    public BlockingQueue<Tweet> getTweets() {
        return tweets;
    }

    public void start() throws IOException, TwitterException {
        twitter.sample();
    }

    private AccessToken getAccessToken() throws TwitterException, IOException, BackingStoreException {
        Preferences prefs = Preferences.userNodeForPackage(getClass());
        String token = prefs.get("twitter.access.token", null);
        String tokenSecret = prefs.get("twitter.access.token.secret", null);
        AccessToken result = null;
        if (token == null) {
            result = authenticate();
            token = result.getToken();
            tokenSecret = result.getTokenSecret();
            prefs.put("twitter.access.token", token);
            prefs.put("twitter.access.token.secret", tokenSecret);
            prefs.flush();
        } else {
            result = new AccessToken(token, tokenSecret);
        }
        return result;
    }
    
    private AccessToken authenticate() throws TwitterException, IOException {
        TwitterStream t = factory.getOAuthAuthorizedInstance(consumerKey, consumerSecret);
        RequestToken requestToken = t.getOAuthRequestToken();
        AccessToken accessToken = null;
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        while (null == accessToken) {
          System.out.println("Open the following URL and grant access to your account:");
          System.out.println(requestToken.getAuthorizationURL());
          System.out.print("Enter the PIN(if aviailable) or just hit enter.[PIN]:");
          String pin = br.readLine();
          try{
             if(pin.length() > 0){
               accessToken = t.getOAuthAccessToken(requestToken, pin);
             }else{
               accessToken = t.getOAuthAccessToken();
             }
          } catch (TwitterException te) {
            if(401 == te.getStatusCode()){
              System.out.println("Unable to get the access token.");
            }else{
              te.printStackTrace();
            }
          }
        }
        return accessToken;
    }
    
    public void setConcepts(ConceptMap concepts) {
        this.concepts = concepts;
    }

    public ConceptMap getConcepts() {
        return concepts;
    }

    @Override
    public void onDeletionNotice(StatusDeletionNotice arg0) {
    }

    @Override
    public void onException(Exception arg0) {
        System.out.println(arg0);
    }

    @Override
    public void onStatus(Status status) {
        List<Individual> individuals = concepts.getConcepts(status.getText());
        if (individuals.size() > 1) {
            Tweet tweet = new Tweet();
            tweet.termVector = individuals;
            tweet.text = status.getText();
            tweet.created = status.getCreatedAt();
            tweet.creator = status.getUser();
            tweet.added = new Date();
            tweets.add(tweet);
            //System.out.println(status.getText()+"\t"+individuals);
        }
    }

    public void onScrubGeo(int x,long y) {
    }

    @Override
    public void onTrackLimitationNotice(int arg0) {
        System.out.println("On Track Limitation Notice:\t"+arg0);
    }

    public static void main(String[] args) throws CorruptIndexException, LockObtainFailedException, IOException, TwitterException, BackingStoreException {
        TweetQueue queue = new TweetQueue(args[0]);
        queue.start();
        System.out.println("Back?");
    }
}
